import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Button, Balloon, Tag } from '@teamix/ui';
import Pagination from 'components/commonPagination';
import { ButtonIcon, YunxiaoIcon, Title, Body, BodyContent, Content } from '@alife/devops-ui';
import { ENUM, ORGANIZATION_ADMIN_ROLES, GROUP_ADMIN_ROLES } from 'utils/constants.js';
import utils from 'utils/index';
import { navigate } from 'utils/router';
import List from 'components/groupList';
import TextAvatar from '@txdfe/at-text-avatar';
import GroupHomeSkeleton from 'components/skeleton/groupHome';
import ListLoading from 'atComponents/ListLoading';
import ListEmpty from 'atComponents/ListEmpty';
import MemberList from 'components/memberList';
import { access } from 'components/accessContainer/util';
import CreateGroupModal from 'components/createGroupModal';
import CreateProjectModal from 'components/createProjectModal/loadable';
import * as actions from '../actions/index';
import GroupTitle from './title';
import AddBtn from './title/btn';
import { enterPage, Perf } from 'utils/track';
import intl from '../../../../../../../locale';

const { user_role } = window.FORCE.organization;
const { visibility_levels } = ENUM;

class Root extends Component {
  static propTypes = {
    groupList: PropTypes.arrayOf(PropTypes.object),
    currentPage: PropTypes.number,
    total: PropTypes.number,
    order_by: PropTypes.string,
    navKey: PropTypes.string,
  };

  static defaultProps = {
    groupList: null,
    currentPage: 1,
    total: 0,
    order_by: 'updated_at',
    navKey: '',
  };

  state = {
    membersDialogVisible: false,
    membersDialogGroup: {},
    createProjectModalShow: false,
    createGroupModalShow: false,
  };

  componentDidMount() {
    enterPage('Group-sub', {
      sendPerf: false,
    });

    // 获取到设置后，再获取分页（placeholder文案根据设置修改）
    this.props.getCreateAccess(() => {
      this.props.getGroups(1);
    });
  }

  componentDidUpdate(prevProps) {
    const { pageInfo } = this.props;
    const { pageInfo: prevPageInfo } = prevProps;
    // 切组的时候
    if (
      prevPageInfo.pathResource.type === 'GROUP' &&
      pageInfo.pathResource.type === 'GROUP' &&
      prevPageInfo.pathResource.id &&
      pageInfo.pathResource.id &&
      prevPageInfo.pathResource.id !== pageInfo.pathResource.id
    ) {
      this.props.resetData();
      this.props.getCreateAccess(() => {
        this.props.getGroups(1);
      });
    }
  }

  componentWillUnmount() {
    this.props.resetData();
  }

  onPageChange = (value) => {
    this.props.getGroups(value);
  };

  onPageSizeChange = (pageSize) => {
    this.props.getGroups(1, pageSize);
  };

  closeModal = (type) => {
    this.setState({
      [type]: false,
    });
  };

  openModal = (type) => {
    this.setState({
      [type]: true,
    });
  };

  filterLevel = (level) => {
    let label = '';
    visibility_levels.forEach((item) => {
      if (item.value === Number(level)) {
        label = item.label;
      }
    });
    return label;
  };

  handleExpand = (e, id, isExpanded) => {
    e.stopPropagation();
    e.preventDefault();
    if (isExpanded) {
      // 展开后收起,数据清空
      this.props.updateSubGroupMap(id);
    } else {
      this.props.getSubGroups(id);
    }
  };

  getCreateGroupAccess = () => {
    const { create_group } = this.props;
    // 完全根据接口判断即可
    return create_group.allow;
  };

  getCreateProjectAccess = () => {
    const { create_repo } = this.props;
    return create_repo.allow;
  };

  getDataSource = (groupList) => {
    const { subGroupMap } = this.props;
    return groupList
      ? groupList.map((group) => {
          const subGroup = subGroupMap[group.id];
          const isLoading = subGroup && subGroup.isLoadingSubGroup;
          const isExpanded = subGroup && subGroup.isExpanded;
          // 是不是库
          const isProject = group.type === 'project';
          const leftTriangle = isLoading ? (
            <ButtonIcon name="loading-fill" />
          ) : (
            <ButtonIcon
              name={`trilateral-${isExpanded ? 'down' : 'right'}-fill`}
              onClick={(e) => {
                this.handleExpand(e, group.id, isExpanded);
              }}
            />
          );

          // 企业管理员或者组管理员
          const isAdmin =
            access(ORGANIZATION_ADMIN_ROLES, user_role) ||
            access(GROUP_ADMIN_ROLES, ENUM.access_level[group.access_level]);
          const showTriangle = !isProject && (group.group_count || group.project_count);
          return {
            left: (
              <span>
                {showTriangle ? leftTriangle : null}
                {isProject ? (
                  <span className={'code-project-btn ml32'}>
                    <YunxiaoIcon type="code-basement-line" />
                  </span>
                ) : (
                  <span className={`code-group-btn ${showTriangle ? '' : 'ml32'}`}>
                    <YunxiaoIcon type={'folder-line'} />
                  </span>
                )}

                <TextAvatar text={group.path.toUpperCase()} image={group.avatar_url} isCover />
              </span>
            ),

            body: {
              title: (
                <span
                  className="project-list-item-title one-line-ellipsis"
                  style={{ display: 'flex', alignItems: 'center' }}
                >
                  <Title trigger={<span>{group.name}</span>}>
                    <div>{group.name}</div>
                  </Title>
                  {group.demo_project ? (
                    <Tag className="demo-repo-tag">
                      {intl.get({
                        id: 'code-assets.groupHome.containers.root.SampleCodeLibrary',
                        defaultMessage: '示例代码库',
                      })}
                    </Tag>
                  ) : null}
                  {group.archived ? (
                    <Tag className="demo-repo-tag" type="primary" color="error">
                      {intl.get({
                        id: 'code-assets.groupHome.containers.root.Archived',
                        defaultMessage: '已归档',
                      })}
                    </Tag>
                  ) : null}
                </span>
              ),

              description: [
                <span className="project-list-item-desc">
                  {group.description ? (
                    <React.Fragment>
                      <span className="project-list-item-desc-project-desc">
                        <Title trigger={<span>{group.description}</span>}>
                          <div>{group.description}</div>
                        </Title>
                      </span>
                      <span className="project-list-item-desc-divider">·</span>
                    </React.Fragment>
                  ) : null}
                  <span className="project-list-item-desc-time">
                    {`${intl.get({
                      id: 'code-assets.src.utils.locale.UpdatedOn',
                      defaultMessage: '更新于',
                    })}${utils.getBeautyTime(group.updated_at)}`}
                  </span>
                </span>,
              ],
            },

            middle: {
              items: isProject
                ? []
                : [
                  <Balloon.Tooltip
                    align="t"
                    trigger={
                      <div style={{ width: 60 }}>
                        <Button type="normal" text className="normal-color">
                          <YunxiaoIcon type="folder-line" /> {group.group_count}
                        </Button>
                      </div>
                      }
                  >
                    {intl.get({
                        id: 'code-assets.groupHome.containers.root.SubcodeGroup',
                        defaultMessage: '子代码组',
                      })}
                  </Balloon.Tooltip>,
                  <Balloon.Tooltip
                    align="t"
                    trigger={
                      <div style={{ width: 60 }}>
                        <Button type="normal" text className="normal-color">
                          <YunxiaoIcon type="code-basement-line" /> {group.project_count}
                        </Button>
                      </div>
                      }
                  >
                    {intl.get({
                        id: 'code-assets.groupHome.containers.root.CodeBase',
                        defaultMessage: '代码库',
                      })}
                  </Balloon.Tooltip>,
                  ],
            },

            right: {
              hoverItems: [
                isAdmin ? (
                  <Balloon.Tooltip
                    align="t"
                    trigger={
                      <ButtonIcon
                        name="add-members-line"
                        onClick={(e) => {
                          e.stopPropagation();
                          e.preventDefault();
                          this.setState({
                            membersDialogVisible: true,
                            membersDialogGroup: group,
                          });
                        }}
                      />
                    }
                  >
                    {intl.get({
                      id: 'code-assets.groupHome.containers.root.MemberManagement',
                      defaultMessage: '成员管理',
                    })}
                  </Balloon.Tooltip>
                ) : (
                  <Tag size="small">{this.filterLevel(group.visibility_level)}</Tag>
                ),
                isAdmin ? (
                  <Balloon.Tooltip
                    align="t"
                    trigger={
                      <ButtonIcon
                        name="setting-line"
                        component="a"
                        onClick={(e) => {
                          e.stopPropagation();
                          e.preventDefault();
                          // TODO a标签点击无效，待list组件修复
                          navigate(`/${group.path_with_namespace}/settings`);
                        }}
                      />
                    }
                  >
                    {intl.get({
                      id: 'code-assets.groupHome.containers.root.EnableSettings',
                      defaultMessage: '打开设置',
                    })}
                  </Balloon.Tooltip>
                ) : null,
              ],

              items: [<Tag size="small">{this.filterLevel(group.visibility_level)}</Tag>],

              style: {
                width: 100,
              },
            },

            onClick: (e) => {
              e.stopPropagation();
              e.preventDefault();
              navigate(`/${group.path_with_namespace}`, {
                state: { forceUpdate: true },
              });
            },
            container: 'a',
          };
        })
      : [];
  };

  renderMembersDialog = () => {
    // 数据可能是子组也可能是库
    const { membersDialogVisible: visible, membersDialogGroup: group } = this.state;

    if (!visible) {
      return null;
    }

    return (
      <MemberList
        visible={visible}
        pathResourceId={group.id}
        pathResourceType={group.type.toLowerCase()}
        isAdmin
        parentId={group.type.toLowerCase() === 'project' ? group.parent_id : group.namespace_id}
        align="tr br"
        role={ENUM.access_level[group.access_level]}
        onClose={() => {
          this.setState({
            membersDialogVisible: false,
            // membersDialogGroup: {},
          });
        }}
      />
    );
  };

  renderContent = () => {
    const { groupList, subGroupMap } = this.props;
    return (
      <React.Fragment>
        <div className="group-list-border">
          <List
            hasHoverItems
            getDataSource={this.getDataSource}
            groupList={groupList}
            subGroupMap={subGroupMap}
          />
        </div>
        <Perf page={'Group-sub'} />
      </React.Fragment>
    );
  };

  render() {
    const {
      isLoading,
      groupList,
      isLoadingGroupInfo,
      groupInfo,
      is_max_level,
      create_repo,
      group_max_level,
    } = this.props;
    const { createProjectModalShow, createGroupModalShow } = this.state;
    // 根据tab 获取数据
    const dataSource = this.getDataSource(groupList);
    const hasGroupAccess = this.getCreateGroupAccess();
    const hasProjectAccess = this.getCreateProjectAccess();
    let content;
    if (isLoading) {
      content = <GroupHomeSkeleton />;
    } else if (dataSource.length === 0) {
      content = (
        <ListEmpty
          fullPage
          content={
            is_max_level
              ? intl.get({
                  id: 'code-assets.groupHome.containers.root.NoDatabaseAvailable',
                  defaultMessage: '暂无库',
                })
              : intl.get({
                  id: 'code-assets.groupHome.containers.root.NoChildGroupsOrDatabases',
                  defaultMessage: '暂无子组/库',
                })
          }
          description={
            !is_max_level ? (
              <div>将代码库组织在组中，工作方式与文件夹类似，支持按组维护成员权限</div>
            ) : (
              <div>
                {intl.get({
                  id: 'code-assets.groupHome.containers.root.ACodeGroupIsA',
                  defaultMessage: '代码组是代码库的集合',
                })}

                <br />
                {intl.get({
                  id: 'code-assets.groupHome.containers.root.OrganizeCodeLibrariesIntoA',
                  defaultMessage: '将代码库组织在一个代码组中，工作方式与文件夹类似',
                })}

                <br />
                {intl.get({
                  id: 'code-assets.groupHome.containers.root.YouCanSetCodeGroup',
                  defaultMessage: '可以设置代码组成员，管理对组内代码库的权限',
                })}

                <br />
                {intl.get({
                  id: 'code-assets.groupHome.containers.root.TheCodeGroupSeriesLimit',
                  defaultMessage: '超过代码组级数限制 [',
                })}
                {group_max_level}
                {intl.get({
                  id: 'code-assets.groupHome.containers.root.YouCannotCreateASubcode',
                  defaultMessage: '级]，不允许新建子代码组',
                })}
              </div>
            )
          }
          image="none"
          btns={[
            <AddBtn
              hasGroupAccess={hasGroupAccess}
              hasProjectAccess={hasProjectAccess}
              openModal={this.openModal}
              message={create_repo.message}
              isListEmpty
            />,
          ]}
        />
      );
    } else {
      content = this.renderContent(dataSource);
    }

    if (isLoadingGroupInfo) {
      return <ListLoading className={'organization-content-loading'} />;
    }

    const { currentPage, total, pageSize } = this.props;

    return (
      <>
        <GroupTitle
          {...this.props}
          hasGroupAccess={hasGroupAccess}
          hasProjectAccess={hasProjectAccess}
          openModal={this.openModal}
        />
        <Body>
          <BodyContent>
            <Content>{content}</Content>
            <Pagination
              onChange={this.onPageChange}
              onPageSizeChange={this.onPageSizeChange}
              current={currentPage}
              total={total}
              pageSize={pageSize}
            />
          </BodyContent>
        </Body>
        {this.renderMembersDialog()}
        {createProjectModalShow && (
          <CreateProjectModal
            closeModal={() => {
              this.closeModal('createProjectModalShow');
            }}
            isSubgroup
            groupAccess={groupInfo.visibility_level}
            isModalOpen={createProjectModalShow}
            onCreateSuccess={() => {
              this.props.updateData({
                createRepositorySuccess: true,
              });
            }}
          />
        )}

        {createGroupModalShow && (
          <CreateGroupModal
            closeModal={() => {
              this.closeModal('createGroupModalShow');
            }}
            isSubgroup
            groupAccess={groupInfo.visibility_level}
            isModalOpen={createGroupModalShow}
          />
        )}
      </>
    );
  }
}

export default connect(
  (state) => ({
    ...state.group.groupHome,
    pageInfo: state.root.pageInfo,
    isLoadingGroupInfo: state.group.root.isLoadingGroupInfo,
    groupInfo: state.group.root.groupInfo,
  }),
  (dispatch) => bindActionCreators(actions, dispatch),
)(Root);
